﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.IO;

namespace Framework.Common
{
    /// <summary>
    /// XML utility class.
    /// </summary>
    public static class XmlIOHelper
    {
        #region Public methods

        /// <summary>
        /// Gets a XML document from a file.
        /// </summary>
        /// <param name="fileName">Full path to file.</param>
        /// <returns>The XML document from a file.</returns>
        public static XmlDocument GetXmlDocument(string fileName)
        {
            if (string.IsNullOrEmpty(fileName))
            {
                throw new ArgumentNullException("fileName");
            }

            if (!File.Exists(fileName))
            {
                throw new ArgumentException(String.Format(@"The ""{0}"" file doesn't exist", fileName));
            }

            XmlDocument xmlDocument = new XmlDocument();
            xmlDocument.Load(fileName);
            return xmlDocument;

        }

        /// <summary>
        /// Gets a XML document from a stream.
        /// </summary>
        /// <param name="inputStream">The input stream.</param>
        /// <returns>The XML document from a stream.</returns>
        public static XmlDocument GetXmlDocument(Stream inputStream)
        {
            if (inputStream == null)
            {
                throw new ArgumentNullException("inputStream");
            }

            XmlDocument xmlDocument = new XmlDocument();
            xmlDocument.Load(inputStream);
            return xmlDocument;
        }

        /// <summary>
        /// Getsb a XML document from a text.
        /// </summary>
        /// <param name="text">XML text.</param>
        /// <returns>The XML document from a text.</returns>
        public static XmlDocument GetXmlDocumentFromText(string text)
        {
            if (string.IsNullOrEmpty(text))
            {
                throw new ArgumentNullException("text");
            }

            XmlDocument xmlDocument = new XmlDocument();
            xmlDocument.LoadXml(text);
            return xmlDocument;
        }

        /// <summary>
        /// Gets a XElement from a file.
        /// </summary>
        /// <param name="fileName">Full path to file.</param>
        /// <returns>The XElement from a file.</returns>
        public static XElement GetXElement(string fileName)
        {
            if (string.IsNullOrEmpty(fileName))
            {
                throw new ArgumentNullException("fileName");
            }

            if (!File.Exists(fileName))
            {
                throw new ArgumentException(String.Format(@"The ""{0}"" file doesn't exist", fileName));
            }

            return XElement.Load(fileName);
        }

        /// <summary>
        /// Gets a XElement from a stream.
        /// </summary>
        /// <param name="inputStream">The input stream.</param>
        /// <returns>The XElement from a stream.</returns>
        public static XElement GetXElement(Stream inputStream)
        {
            if (inputStream == null)
            {
                throw new ArgumentNullException("inputStream");
            }

            return XElement.Load(new XmlTextReader(inputStream));
        }

        /// <summary>
        /// Gets a XElement from a text.
        /// </summary>
        /// <param name="text">The XML text.</param>
        /// <returns>The XElement from a text.</returns>
        public static XElement GetXElementFromText(string text)
        {
            if (string.IsNullOrEmpty(text))
            {
                throw new ArgumentNullException("text");
            }

            return XElement.Parse(text);
        }

        /// <summary>
        /// Puts a XML document into a file.
        /// </summary>
        /// <param name="xmlDocument">The XML document.</param>
        /// <param name="fileName">Full path to file.</param>
        /// <param name="encoding">Encoding (optional: may be null).</param>
        public static void PutXmlDocument(XmlDocument xmlDocument, string fileName, Encoding encoding)
        {
            if (xmlDocument == null)
            {
                throw new ArgumentNullException("xmlDocument");
            }

            if (string.IsNullOrEmpty(fileName))
            {
                throw new ArgumentNullException("fileName");
            }

            XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();
            if (encoding != null)
            {
                xmlWriterSettings.Encoding = encoding;
            }
            XmlWriter xmlWriter = XmlWriter.Create(fileName, xmlWriterSettings);
            xmlDocument.Save(xmlWriter);
            xmlWriter.Close();
        }

        /// <summary>
        /// Puts a XML document into a stream.
        /// </summary>
        /// <param name="xmlDocument">The XML document.</param>
        /// <param name="outputStream">The output stream.</param>
        /// <param name="encoding">Encoding (optional: may be null).</param>
        public static void PutXmlDocument(XmlDocument xmlDocument, Stream outputStream, Encoding encoding)
        {
            if (xmlDocument == null)
            {
                throw new ArgumentNullException("xmlDocument");
            }

            if (outputStream == null)
            {
                throw new ArgumentNullException("outputStream");
            }

            XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();
            if (encoding != null)
            {
                xmlWriterSettings.Encoding = encoding;
            }
            XmlWriter xmlWriter = XmlWriter.Create(outputStream, xmlWriterSettings);
            xmlDocument.Save(xmlWriter);
            xmlWriter.Close();
        }

        /// <summary>
        /// Puts a XML document into a string.
        /// </summary>
        /// <param name="xmlDocument">The XML document.</param>
        /// <param name="text">Receives the XML text.</param>
        public static void PutXmlDocumentToText(XmlDocument xmlDocument, out string text)
        {
            if (xmlDocument == null)
            {
                throw new ArgumentNullException("xmlDocument");
            }

            StringBuilder buffer = new StringBuilder();
            XmlWriter xmlWriter = XmlWriter.Create(buffer);
            xmlDocument.Save(xmlWriter);
            xmlWriter.Close();

            text = buffer.ToString();
        }

        /// <summary>
        /// Puts a XElement into a file.
        /// </summary>
        /// <param name="xElement">The XElement.</param>
        /// <param name="fileName">Full path to file.</param>
        /// <param name="encoding">Encoding (optional: may be null).</param>
        public static void PutXElement(XElement xElement, string fileName, Encoding encoding)
        {
            if (xElement == null)
            {
                throw new ArgumentNullException("xElement");
            }

            if (string.IsNullOrEmpty(fileName))
            {
                throw new ArgumentNullException("fileName");
            }

            XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();
            if (encoding != null)
            {
                xmlWriterSettings.Encoding = encoding;
            }

            XmlWriter xmlWriter = XmlWriter.Create(fileName, xmlWriterSettings);
            xElement.Save(xmlWriter);
            xmlWriter.Close();
        }

        /// <summary>
        /// Puts a XElement into a stream.
        /// </summary>
        /// <param name="xElement">The XElement.</param>
        /// <param name="outputStream">The output stream.</param>
        /// <param name="encoding">Encoding (optional: may be null).</param>
        public static void PutXElement(XElement xElement, Stream outputStream, Encoding encoding)
        {
            if (xElement == null)
            {
                throw new ArgumentNullException("xElement");
            }

            if (outputStream == null)
            {
                throw new ArgumentNullException("outputStream");
            }

            XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();
            if (encoding != null)
            {
                xmlWriterSettings.Encoding = encoding;
            }

            XmlWriter xmlWriter = XmlWriter.Create(outputStream, xmlWriterSettings);
            xElement.Save(xmlWriter);
            xmlWriter.Close();

        }

        /// <summary>
        /// Puts a XElement into a string.
        /// </summary>
        /// <param name="xElement">The XElement.</param>
        /// <param name="text">Receives the XML text.</param>
        public static void PutXElementToText(XElement xElement, out string text)
        {
            if (xElement == null)
            {
                throw new ArgumentNullException("xElement");
            }

            StringBuilder buffer = new StringBuilder();
            XmlWriter xmlWriter = XmlWriter.Create(buffer);
            xElement.Save(xmlWriter);
            xmlWriter.Close();

            text = buffer.ToString();
        }
        #endregion
    }
}
